'''
Created on 19 janv. 2012

@author: e0009298
'''

import cherrypy

from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.ext.db import BadKeyError

from formencode import Invalid

from mymoney.models import Payee, Category, Account, Operation
from mymoney.forms import PayeeForm, CategoryForm, AccountForm, OperationForm
from mymoney.filters import datetimeformat

from jinja2 import Environment, FileSystemLoader

import datetime
import simplejson

env = Environment(loader=FileSystemLoader('templates'))

# Loads filters
env.filters['datetimeformat'] = datetimeformat

accounts = Account.gql("ORDER BY account_type, title ASC")

class AccountHandler:
    @cherrypy.expose
    def list(self):
        tmpl = env.get_template('account_list.html')
        
        return tmpl.render(accounts = accounts)
    
    @cherrypy.expose
    def submit(self, cancel = False, key = None, **data):
        account = None
        if cherrypy.request.method == 'POST':
            if cancel:
                raise cherrypy.HTTPRedirect('/account/list')
            
            form = AccountForm()
            
            try:
                data = form.to_python(data)
                
                if key == None:
                    data['archived_amount'] = 0;
                    account = Account(**data)
                else:
                    account = Account.get(key)
                    account.title = data['title']
                    account.account_type = data['account_type']
                    account.number = data['number']
                    account.bank_name = data['bank_name']
                    account.initial_amount = data['initial_amount']                               
                
                if users.get_current_user():
                    account.author = users.get_current_user()
                account.put()                
                
                raise cherrypy.HTTPRedirect('/account/list')
            except Invalid, e:
                errors = e.unpack_errors()
        else:
            if key != None:
                account = Account.get(key)
            errors = {}
        
        tmpl = env.get_template('account_submit.html')
        return tmpl.render(errors = errors, account = account, accounts = accounts)
    
    @cherrypy.expose
    def delete(self, key):
        try:
            account = Account.get(key)
            
            account.delete()
            raise cherrypy.HTTPRedirect('/account/list')
        except BadKeyError, e:
            raise cherrypy.HTTPError(status = 404, message = 'The account cannot be found.')
    
    @cherrypy.expose
    def view(self, cancel = False, key = None, **data):
        operation = None
        errors = {}
        form = OperationForm()
        
        if cherrypy.request.method == 'POST':
            if cancel:
                raise cherrypy.HTTPRedirect('/account/view?key=' + key)
        
        try:
            account = Account.get(key)
        except BadKeyError, e:
            raise cherrypy.HTTPError(status = 404, message = 'The account cannot be found.')
        
        if cherrypy.request.method == 'POST':
            try:
                data = form.to_python(data)
                
                operation = Operation(srcAccount = account, 
                                      paymode = data['paymode'],
                                      date = data['date'],
                                      payee = Payee.get(data['payee']),
                                      category = Category.get(data['category']),
                                      expense = data['expense'],
                                      income = data['income'],
                                      status = 'PENDING')
                
                if users.get_current_user():
                    operation.author = users.get_current_user()
                operation.put()
                
            except Invalid, e:
                errors = e.unpack_errors()

        operations_src = db.GqlQuery('SELECT __key__ FROM Operation WHERE srcAccount = :srcAccount', srcAccount = account).fetch(100)
        operations_dest = db.GqlQuery('SELECT __key__ FROM Operation WHERE destAccount = :destAccount', destAccount = account).fetch(100)
        
        operations_keys = list(set(operations_src + operations_dest))
        
        operations = Operation.gql('WHERE __key__ IN :keys', keys = operations_keys)
                
        tmpl = env.get_template('account_view.html')
        
        payees = Payee.all()
        categories = Category.all()
                
        return tmpl.render(account = account, operations = operations, payees = payees, categories = categories, errors = errors, accounts = accounts)
        

class PayeeHandler:     
    
    @cherrypy.expose
    def list(self):
        tmpl = env.get_template('payee_list.html')
        payees = db.GqlQuery("SELECT * FROM Payee ORDER BY title ASC") # LIMIT 10")
        
        return tmpl.render(payees = payees, accounts = accounts)
    
    @cherrypy.expose
    @cherrypy.tools.json_out()
    @cherrypy.tools.allow(methods=['POST'])
    def get(self, key=None):
        payee = Payee.get(key)
#        return {"payee": simplejson.JSONEncoder.default(self, payee) }
        return {"result": "SUCCESS", "payee": payee.title }
      
    @cherrypy.expose
    @cherrypy.tools.json_out()
    @cherrypy.tools.allow(methods=['POST'])
    def submit(self, **data):
        form = PayeeForm()
        try:
            data = form.to_python(data)
            payee = Payee(**data)
            if users.get_current_user():
                payee.author = users.get_current_user()
                    
            payee.updated_at = datetime.datetime.now()
            payee.put()
            
            payees = db.GqlQuery("SELECT * FROM Payee ORDER BY title ASC")
            
            tmpl = env.get_template('payee_list_tmpl.html')
            html = tmpl.render(payees = payees)
            
            return { "result": "SUCCESS", "html": html, "id": payee.key().__str__() }
        except Invalid, e:
            return { "result": "FAILED", "errors": e.unpack_errors() }

class CategoryHandler:     
    
    @cherrypy.expose
    def list(self):
        tmpl = env.get_template('category_list.html')
        categories = Category.gql("ORDER BY title ASC") # LIMIT 10")
        
        return tmpl.render(categories = categories, accounts = accounts)
    
##    @cherrypy.tools.allow(methods=['POST'])
    @cherrypy.expose
    def submit(self, cancel=False, **data):
        if cherrypy.request.method == 'POST':
            if cancel:
                raise cherrypy.HTTPRedirect('/')
            
            form = CategoryForm()
            try:
                data = form.to_python(data)
                
                category = Category(**data)
                
                if users.get_current_user():
                    category.author = users.get_current_user()
                category.put()
                
                raise cherrypy.HTTPRedirect('/category/list')
            except Invalid, e:
                errors = e.unpack_errors()
        else:
            errors = {}
        
        tmpl = env.get_template('category_submit.html')
        return tmpl.render(errors = errors, accounts = accounts)